package com.newworld.mybatis.many2many;

import com.newworld.mybatis.many2many.mapper.GroupMapper;
import com.newworld.mybatis.many2many.mapper.TestConcurrent;
import com.newworld.mybatis.many2many.mapper.UserGroupMapper;
import com.newworld.mybatis.many2many.mapper.UserMapper;
import com.newworld.mybatis.many2many.model.Group;
import com.newworld.mybatis.many2many.model.User;
import com.newworld.mybatis.many2many.model.UserGroup;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by George on 2018/8/20.
 * Main
 */
public class Main {
    private static SqlSessionFactory sqlSessionFactory;
    private static Reader reader;

    static {
        try {
            reader = Resources.getResourceAsReader("config/Configure.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSession() {
        return sqlSessionFactory;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 2018-08-20 需要测试验证。
        // testAddGroup();
        // testAddUser();
        // testAddUserGroup();
//        testGetGroupAndUsers();

        testConcurrent();
    }

    private static void testConcurrent() {
        SqlSession session = sqlSessionFactory.openSession();
        try {
            List<Thread> threads = new ArrayList<>(100);
            for (int i = 1; i <= 100; i++) {
                threads.add(new Thread(new TestConcurrentInsertData("thread " + i)));
            }

            for (Thread thread : threads) {
                thread.start();
            }

            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } finally {
            session.close();
        }
    }

    public static void testGetGroupAndUsers() {
        UserGroup userGroup = new UserGroup();
        SqlSession session = sqlSessionFactory.openSession();
        try {
            GroupMapper groupMaper = session.getMapper(GroupMapper.class);
            Group group = groupMaper.getGroup(1);
            System.out.println("Group => " + group.getGroupName());
            List<User> users = group.getUsers();
            for (User user : users) {
                System.out.println("\t:" + user.getId() + "\t"
                        + user.getUsername());
            }
        } finally {
            session.close();
        }
    }

    public static void testAddUserGroup() {
        UserGroup userGroup = new UserGroup();
        userGroup.setGroupId(1);
        userGroup.setUserId(2);
        SqlSession session = sqlSessionFactory.openSession();
        try {
            UserGroupMapper userGroupMaper = session
                    .getMapper(UserGroupMapper.class);
            userGroupMaper.insertUserGroup(userGroup);

            session.commit();
        } finally {
            session.close();
        }

    }

    public static void testAddUser() {
        // TODO Auto-generated method stub
        SqlSession session = sqlSessionFactory.openSession();
        try {
            User user = new User();
            user.setUsername("User-name-1");
            user.setMobile("13838009988");
            UserMapper userMaper = session.getMapper(UserMapper.class);
            userMaper.insertUser(user);
            session.commit();
            // System.out.println(user.getGroupId());
        } finally {
            session.close();
        }
    }

    public static void testAddGroup() {
        // TODO Auto-generated method stub
        SqlSession session = sqlSessionFactory.openSession();
        try {
            Group group = new Group();
            group.setGroupName("用户组-1");
            GroupMapper groupMapper = session.getMapper(GroupMapper.class);
            groupMapper.insertGroup(group);
            session.commit();
            System.out.println(group.getGroupId());
        } finally {
            session.close();
        }
    }


    private static class TestConcurrentInsertData implements Runnable {
        private String name;

        public TestConcurrentInsertData(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try (SqlSession session = sqlSessionFactory.openSession(true);) {
                TestConcurrent mapper = session.getMapper(TestConcurrent.class);
                mapper.insert(this.name, System.nanoTime());
                int num = mapper.getSum();
                System.out.println(this.name + " current sum=" + num);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
